iT邦幫忙

2025 iThome 鐵人賽

DAY 24
0
生成式 AI

南桃AI重生記系列 第 24

08-01:南桃AI創意市集的盛大成功

  • 分享至 

  • xImage
  •  

第八章第一節:南桃AI創意市集的盛大成功

https://ithelp.ithome.com.tw/upload/images/20250909/200461604vSv8tnlq1.png

破曉時分的緊張與期待

週六清晨五點,南桃小鎮還沉浸在晨霧中,但市集現場已經燈火通明。小潔、大財、霈姊和阿美圍在「作戰指揮中心」——一個搭建在市集中央的白色帳篷裡,最後一次檢視所有系統。

「所有設備綠燈,」大財盯著筆電螢幕,「Google生態系運作完美,網路頻寬充足,備援系統待命。」

小潔深吸一口氣,看著Google Calendar上標示的倒數時間:「距離開幕還有三小時。我們準備好了嗎?」

霈姊抱著剛醒來的小肉丸,眼中既有緊張也有期待:「我從來沒想過我們真的能做到這樣的規模。」

阿美興奮地指著Google Analytics的即時數據:「妳們看!現在已經有超過五千人在線上關注我們,而且還在持續增加!」

參展商的陸續到場

上午七點,第一批參展商開始到場。讓小潔驚喜的是,除了原本報名的本地攤商,還有許多意想不到的參與者。

「葉候選人!」一位穿著傳統客家服飾的老婆婆向小潔招手,「我是製作客家美食的阿桂嬤,聽說妳們要辦市集,我特地趕來參加!」

阿桂嬤身後跟著一群年輕人,推著裝滿客家粄條、紅龜粿、艾草粿的推車。「這些是我們客家社區的年輕人,他們說要用AI幫我們推廣傳統美食!」

大財立刻啟動Google翻譯和資料收集系統:「太好了!我們馬上為您建立攤位資訊,並且用AI生成多語言介紹。」

不遠處,原住民歌手阿力正在調試音響設備。「我要唱傳統古謠,但用現代編曲,還要配合LED燈光秀!」他對著音控台興奮地說。

阿美拿起攝影機開始記錄:「這太棒了!我們本來只是想展示AI技術,結果變成了南桃文化的大匯演!」

志工團隊的完美配合

上午八點,志工們陸續抵達。讓小潔意外的是,除了原本報名的大學生,還有許多意想不到的面孔。

「小潔姊!」一群穿著統一T恤的高中生跑了過來,「我們是南桃高中的學生會,聽說妳們在辦AI市集,我們全校都想來幫忙!」

學生會長小婷興奮地說:「我們有一百多個同學報名當志工,還有電腦社的同學想展示他們寫的程式!」

霈姊看著這群充滿活力的年輕人,眼中湧起感動:「這就是我們想要的效果。讓年輕人看到科技的美好,看到未來的可能性。」

Google Forms的志工管理系統立刻派上用場。大財快速地為新加入的志工分配任務:

「攤位引導組:負責協助參展商設置和解答問題」
「技術支援組:處理設備問題和系統維護」
「多語言服務組:協助外國朋友和新住民」
「活動記錄組:拍攝和直播活動過程」
「緊急應變組:處理突發狀況」

媒體的意外關注

上午九點,小潔接到阿美慌張的電話:「小潔!妳快來看!有電視台來了!」

小潔急忙跑到市集入口,看到三台新聞車停在路邊,記者和攝影師正在架設設備。

「請問您是葉小潔候選人嗎?」一位年輕的女記者主動走過來,「我是民視新聞的記者林小芳。我們聽說南桃要舉辦全台第一個AI創意市集,特地來採訪!」

另一位年長的記者也走了過來:「我是公視的王記者。這個活動在網路上引起很大的討論,我們想了解這是如何辦到的。」

小潔既驚喜又緊張:「我們只是想用科技為鄉鎮帶來一些改變...沒想到會受到這麼多關注。」

大財立刻啟動媒體應對流程,Google Sheets裡的媒體聯絡清單立即派上用場:「我們已經準備好媒體資料包,包括活動介紹、技術說明和採訪行程安排。」

市集正式開幕的震撼場面

上午十點整,南桃AI創意市集正式開幕。小潔站在主舞台上,看著台下黑壓壓的人群,心中湧起難以言喻的激動。

「歡迎大家來到南桃AI創意市集!」小潔的聲音透過音響系統傳遍整個會場,「今天,我們要證明科技不是冷冰冰的工具,而是能夠溫暖人心、連結社群的橋樑!」

台下響起熱烈的掌聲。讓小潔驚喜的是,人群中不只有本地居民,還有許多外地遊客,甚至有外國面孔。

「現在,讓我們一起見證傳統與科技的美麗結合!」

隨著小潔的話音落下,整個市集瞬間活了起來。

傳統文化與AI技術的完美融合

客家美食AI推薦系統

阿桂嬤的攤位成為第一個亮點。大財協助她建立了一個AI美食推薦系統,透過Google Lens識別食材,即時生成營養分析和客家文化介紹。

「這個粄條有一百年的歷史,」阿桂嬤對著一群遊客說道,「我的阿婆傳給我的配方,現在用這個神奇的機器,可以告訴妳們每一種食材的營養價值和文化故事!」

遊客們紛紛拿出手機掃描QR code,立刻看到詳細的介紹:

【客家粄條 - AI美食介紹】
歷史:源自客家先民的智慧,使用在來米製作
營養:富含碳水化合物,低脂肪,容易消化
文化意義:代表客家人勤儉持家的精神
製作工藝:手工製作,需要精準的水量控制
推薦搭配:韭菜、豆芽菜、客家鹹菜

「太神奇了!」一位台北來的遊客驚嘆,「我從來不知道吃個粄條還有這麼多學問!」

原住民音樂的AI視覺化

阿力的表演更是驚艷全場。他的傳統古謠搭配AI生成的視覺效果,讓現場觀眾如癡如醉。

當阿力唱起祖先的歌謠時,LED螢幕上同步顯示著AI解讀的音樂情感,轉化成流動的色彩和圖案:

  • 低沉的男聲對應深藍色的山巒
  • 高亢的和聲化作金黃色的陽光
  • 鼓聲的節拍變成脈動的心跳圖案

「這是我第一次『看見』音樂的靈魂,」一位音樂系的大學生激動地說,「科技讓我更深刻地理解原住民文化的美。」

在地農產品的智慧行銷

南桃的農民們也積極參與。老農阿伯帶來了他種的有機蔬菜,在AI協助下建立了完整的產銷履歷系統。

遊客只要掃描蔬菜上的QR code,就能看到:

  • 種植過程的照片記錄
  • 土壤和水質檢測報告
  • 農民的種植故事
  • 營養成分分析
  • 烹飪建議和食譜

「我種菜四十年,從來沒想過可以這樣介紹我的菜,」阿伯笑得合不攏嘴,「年輕人真的很厲害!」

年輕世代的創意展現

南桃高中的同學們也展示了他們的創意專案:

「AI詩人」互動裝置

電腦社的同學們開發了一個AI詩歌創作系統,遊客可以輸入關於南桃的關鍵字,AI就會即時創作一首詩:

輸入:「南桃、夕陽、思念」
AI創作:
「南桃小鎮夕陽西,
思念如潮湧心扉,
科技雖新情不變,
故鄉永遠在心間。」

「哇!這比我寫得還好!」一位小朋友驚嘆道。

「時光機」VR體驗

美術社和電腦社合作,用VR技術重現了南桃五十年前的樣貌,讓遊客可以體驗小鎮的歷史變遷。

戴上VR眼鏡的阿嬤感動得流下眼淚:「這就是我小時候的南桃!那棟老房子、那條小河,都還在!」

意想不到的參與者

都市來的創業團隊

中午時分,一群來自台北的年輕創業者出現在市集裡。

「我們在網路上看到這個活動,覺得太有意思了!」領隊的創業者小宇說,「我們想在這裡展示我們開發的農業無人機技術。」

他們現場展示了如何用無人機監測農田狀況,並用AI分析農作物的健康程度。現場的農民們圍觀得津津有味。

「這個可以幫我們省很多時間!」阿伯興奮地說,「以前要走遍整片田才知道哪裡有問題,現在飛一圈就知道了!」

國外觀光客的驚喜發現

更令人意外的是,幾位歐美觀光客也被吸引過來。

「This is amazing!」一位來自德國的遊客Tom驚嘆,「我們在台北聽說這裡有個特別的AI市集,就租車過來看看。這比任何科技展都有趣!」

他的朋友Sarah補充:「在歐洲,我們很少看到科技和傳統文化結合得這麼好的例子。這真是台灣的驕傲!」

大財立刻啟動多語言服務,為外國朋友提供英語導覽,介紹每個攤位的特色和背後的技術原理。

網路上的病毒式傳播

下午兩點,阿美發現了一個驚人的現象:「小潔!妳快看網路上的反應!」

Google Analytics顯示,活動官網的流量在短短幾小時內暴增了五十倍。社群媒體上,#南桃AI市集 的hashtag正在瘋狂傳播。

Facebook上的熱門貼文:
「誰說鄉下地方沒有創新?南桃這個AI市集太驚豔了!傳統客家美食配上AI介紹,我第一次覺得科技這麼有溫度!」(分享數:3,847)

Instagram上的美照:
原住民歌手配上AI視覺效果的照片,獲得了超過一萬個讚,數百則留言都在問「這是在哪裡?」

YouTube直播:
現場直播的觀看人數突破十萬,留言區湧入來自全台各地甚至海外的支持訊息。

「這太不可思議了,」霈姊看著手機螢幕上不斷跳動的數字,「我們只是想辦個小市集,怎麼變成全國關注的焦點了?」

當地居民態度的轉變

最讓小潔感動的,是看到原本對她持保留態度的居民們,開始主動參與和支持。

李大嬸的改變

一直對小潔的「外來者」身份有意見的李大嬸,主動走到小潔面前:

「小潔啊,我要跟妳道歉,」李大嬸的眼中含著淚水,「我以前覺得妳是台北來的,不了解我們鄉下,但今天看到這個市集,我知道我錯了。」

她指著正在排隊購買客家美食的遊客群:「妳讓全台灣的人都知道我們南桃有多好,讓我們的文化被看見。這是我們自己都做不到的事情。」

年輕人的回歸

更令人振奮的是,一些原本在外地工作的南桃年輕人,特地請假回來參加活動。

「我在台中工作三年了,從來沒這麼以南桃為榮過,」返鄉的年輕人小明說,「看到家鄉可以這麼有活力,我在考慮是不是該回來發展。」

他的朋友小華也點頭同意:「對啊,如果南桃真的能變成這樣有創意的地方,我們為什麼還要在外面漂泊?」

長輩們的認同

最保守的鎮民代表陳老爹,也在下午時主動找到小潔:

「小潔,我要承認,我小看妳了,」陳老爹誠懇地說,「我活了七十年,從來沒看過南桃這麼熱鬧,這麼有生氣。妳做到了我們這些老頭子想都不敢想的事情。」

他看著滿滿的人潮和熱絡的活動:「如果妳真的當選,我會全力支持妳的政策。」

電視新聞的即時報導

下午三點,各大電視台開始播出南桃AI市集的新聞報導:

民視新聞:
「南桃小鎮今天舉辦了全台第一個AI創意市集,結合傳統文化與現代科技,吸引了數千人參與,展現了台灣鄉鎮創新的無限可能...」

公視新聞:
「這個由候選人葉小潔發起的活動,不只是一場市集,更是一場科技與人文的對話,讓我們看到AI技術如何真正服務社區,提升在地文化的價值...」

TVBS新聞:
「南桃AI市集的成功,為台灣的鄉鎮發展提供了新的思路,科技不再是都市的專利,也能在鄉村綻放出不同的光彩...」

大財興奮地監控著各種媒體的報導:「我們上了五家電視台的新聞,十幾個網路媒體都在報導,這個影響力太驚人了!」

學術界的關注

傍晚時分,小潔接到一通意想不到的電話。

「請問是葉小潔小姐嗎?我是台大資工系的張教授,」電話那頭傳來溫和的聲音,「我們在網路上看到南桃AI市集的報導,非常感興趣。我們想邀請妳到台大分享這個經驗。」

緊接著,成大、清大、政大的教授們也陸續來電,希望深入了解他們的AI應用模式。

「妳們的實作案例太有價值了,」台科大的李教授在電話中說,「這是AI技術真正落地應用的典範,我們希望能將這個模式推廣到更多鄉鎮。」

阿美難以置信地說:「我們從學生變成了老師的研究對象?這個世界變化太快了!」

政治效應的顯現

對手陣營的震撼

劉校長和他的團隊在辦公室裡緊急開會,看著電視上南桃AI市集的報導,每個人的臉色都很凝重。

「這個影響力太大了,」劉校長的競選總幹事焦急地說,「所有媒體都在正面報導,我們要如何回應?」

劉校長盯著螢幕上小潔被民眾簇擁的畫面,眼中閃爍著複雜的情緒。

市集的成功數據

晚上八點,市集正式結束。大財統計出令人驚嘆的數據:

參與人數:

  • 現場參與者:超過8,000人
  • 線上觀看直播:120,000人次
  • 社群媒體觸及:500,000人次

經濟效益:

  • 攤商營業額:比平常增加300%
  • 觀光收益:為南桃帶來約200萬元的經濟效益
  • 媒體價值:免費宣傳價值超過1,000萬元

技術表現:

  • 系統穩定度:99.8%
  • AI翻譯準確率:95%
  • 用戶滿意度:98.5%

「這些數字太不真實了,」霈姊看著報表,「我們真的做到了這樣的成果?」

團隊的慶祝與反思

晚上十點,市集現場已經恢復平靜。小潔、大財、霈姊和阿美坐在主舞台上,看著滿天星斗,回味這一天的奇蹟。

「我們成功了,」小潔輕聲說道,「但這只是開始。」

大財點點頭:「今天證明了AI技術可以真正服務社區,讓傳統文化重新發光。這為我們的未來政策提供了強大的信心。」

霈姊抱著已經睡著的小肉丸:「我希望小肉丸長大後,能生活在一個科技與人文和諧共存的世界。今天,我們朝這個目標邁出了重要的一步。」

阿美舉起手機,拍下這個歷史性的時刻:「這一天會被記錄在南桃的歷史上,也會被記錄在台灣AI發展的歷史上。」

全國性的迴響

媒體的深度分析

隔天的報紙頭版,幾乎都以南桃AI市集為主題:

聯合報頭版:
「南桃奇蹟:AI如何改變台灣鄉鎮」

自由時報頭版:
「科技下鄉新典範:南桃模式啟示錄」

蘋果日報頭版:
「25歲候選人掀起AI革命」

國際媒體的報導

更令人驚喜的是,國際媒體也開始關注南桃的AI市集:

BBC亞洲版:
「Taiwan's Rural Town Shows How AI Can Preserve Culture」
(台灣鄉鎮展示AI如何保存文化)

CNN國際版:
「Small Town, Big Ideas: Taiwan's AI Revolution」
(小鎮大思維:台灣的AI革命)

日本NHK:
「台湾の地方都市が示すAI活用の新しい可能性」
(台灣地方城市展示AI應用的新可能性)

南桃小鎮的蛻變

觀光人潮的湧入

市集結束後,南桃的觀光人潮並沒有減少。每個週末都有數百位遊客專程前來,希望體驗「小鎮」的魅力。

當地的民宿、餐廳、商店生意都比以前好了三倍以上。

「我們要感謝小潔,」民宿老闆娘開心地說,「她讓世界看見了南桃。」

年輕人的回流

更重要的是,外出工作的年輕人開始有返鄉的念頭。

「家鄉變得這麼有前景,我為什麼還要在外面打拼?」許多年輕人開始這樣思考。

南桃的人口外流問題,幾十年來第一次出現逆轉的跡象。

產業升級的契機

傳統農業也開始導入AI技術,提升產品品質和行銷能力。

小型製造業也在評估導入自動化和AI管理系統的可能性。

南桃正在經歷一場安靜但深刻的產業革命。

期望值的提高

成功也意味著更高的期望。民眾希望看到更多創新專案,媒體持續關注後續發展,政府部門也期待更多政策建議。

「壓力很大,」小潔私下對霈姊說,「但這也是我們證明自己的機會。」

章節尾聲:新的起點

夜深了,南桃小鎮重歸寧靜。但這份寧靜與之前不同,它充滿了希望和可能性。

小潔站在咖啡店的陽台上,看著遠處依然閃爍的市集燈光,心中五味雜陳。

一天前,她還只是一個充滿理想但名不見經傳的年輕候選人。現在,她成為了全國關注的焦點,肩負著無數人的期望。

「這真的是我們想要的嗎?」她問自己。

但當她看到大財還在筆電前工作,阿美還在整理今天的照片和影片,霈姊還在哄著小肉丸睡覺時,她知道答案是肯定的。

他們要的不是名聲,不是關注,而是真正改變這個世界的可能性。

而今天,他們證明了這個可能性是真實存在的。

明天,新的挑戰就會開始。但今晚,他們可以為這個小小的奇蹟感到驕傲。

南桃AI創意市集的成功,不只是一場活動的勝利,更是一個新時代的開始。

在這個新時代裡,科技不再是冷冰冰的工具,而是溫暖人心的橋樑;鄉村不再是被遺忘的角落,而是創新的前沿;年輕人不再是政治的局外人,而是改變的主力軍。

這一切,都始於四個年輕人的夢想,和一個小鎮對未來的信心。


下節預告:成功的喜悅還未散去,新的挑戰就要來臨。小潔團隊將面臨AI技術應用中最複雜的考驗——如何在多元文化的衝突中找到平衡...


若迫不及待想要知道之後的故事發展,可以到鏡文學,故事的部分,我已經都上傳到這裡,歡迎使用打賞功能等📚,是對筆者最實質的鼓勵🥰。ps:實做的部分還是會只放在鐵人賽喔


關於我

我是 Wolke。我是一名專業程式開發者,專長是開發 AI 和程式解決方案。

我投入了不少時間在專業發展上。我是多本書的作者,其中包括《LINE聊天機器人+AI+雲端+開源+程式:輕鬆入門到完整學習》《ChatGPT來襲,未來人人都需具備的運算思維!應用詠唱工程來釋放程式生產力—程式學習/開發篇》。也有出版線上課程,我熱衷於分享我的經驗和技術,幫助其他開發者更好地利用 AI 工具。

也在許多知名大學、論壇、社團擔任講者,如果貴方有需要也歡迎與我聯繫。
2023年 講座 紀錄

最後這篇文章若有切合你的需求,敬請訂閱按讚分享

好書推薦

本系列相關內容已轉載及加強到筆者 2025 年 所出版之

全面掌握 Gemini 開發實務:輕鬆駕馭 Google AI 引擎

  1. 編寫有效的提示:了解如何撰寫清晰、準確的指令,引導 Gemini 模型生成高質量的回應,從日常應用到複雜專案都能得心應手。
  2. 微調 Gemini 模型:深入探索模型微調技巧,根據您的專案需求調整參數,實現個性化應用,讓AI成為您專屬的智慧助理。
  3. 整合 Gemini API:完整解讀 API 功能,學習如何將其融入現有系統或打造全新的應用,充分利用 Google AI 生態系統的強大資源。

購買連結🔗 Momo🛍️ 博客來📚 誠品📘 金石堂📖天瓏

若這篇文章對您有實質幫助🙏,還望購買書籍📚,是對筆者最實質的鼓勵🥰。

實作-08-01:AI創意市集系統整合與現場應用

專案概述

本實作基於故事-08-01中南桃AI創意市集的成功案例,展示如何整合多種AI技術和Google生態系,打造一個完整的智慧市集管理與體驗系統。

系統架構設計

核心系統架構

graph TB
    A[Google Workspace核心] --> B[Google Sheets數據中樞]
    A --> C[Google Calendar時程管理]
    A --> D[Google Sites官網]
    A --> E[Google Forms報名系統]
    A --> F[Google Drive檔案管理]
    
    B --> G[參展商管理]
    B --> H[志工排班]
    B --> I[設備監控]
    B --> J[預算控制]
    B --> K[效果統計]
    
    L[AI應用層] --> M[美食推薦系統]
    L --> N[音樂視覺化]
    L --> O[智慧行銷]
    L --> P[詩歌創作]
    L --> Q[多語言服務]
    
    R[前端體驗] --> S[QR Code掃描]
    R --> T[VR歷史體驗]
    R --> U[即時直播]
    R --> V[社群分享]

1. Google生態系統整合

1.1 數據中樞建設

Google Sheets作為核心數據庫

// 參展商資料庫結構
const exhibitorData = {
  id: "EXH001",
  name: "阿桂嬤客家美食",
  category: "傳統美食",
  location: "A區01號",
  contact: "0912-345-678",
  products: ["客家粄條", "紅龜粿", "艾草粿"],
  aiFeatures: ["營養分析", "文化介紹", "多語言說明"],
  status: "已入場",
  timestamp: "2024-10-26 07:30:00"
};

// 志工排班系統
const volunteerSchedule = {
  id: "VOL001",
  name: "南桃高中小婷",
  group: "攤位引導組",
  shift: "09:00-12:00",
  location: "A區",
  skills: ["中文", "英文", "基礎客語"],
  status: "已報到",
  emergencyContact: "0987-654-321"
};

// 即時監控數據
const realTimeMonitoring = {
  timestamp: new Date(),
  visitors: 8000,
  onlineViewers: 120000,
  systemStatus: "正常",
  networkUsage: "75%",
  powerConsumption: "正常",
  emergencyReports: 0
};

1.2 Google Apps Script自動化

// 自動化數據同步腳本
function autoSyncData() {
  const sheet = SpreadsheetApp.getActiveSheet();
  const calendar = CalendarApp.getDefaultCalendar();
  const drive = DriveApp;
  
  // 同步參展商資料到日曆
  syncExhibitorToCalendar();
  
  // 自動生成QR Code
  generateQRCodes();
  
  // 發送即時通知
  sendRealTimeNotifications();
  
  // 更新網站內容
  updateWebsiteContent();
}

function syncExhibitorToCalendar() {
  const exhibitors = getExhibitorData();
  exhibitors.forEach(exhibitor => {
    const event = calendar.createEvent(
      `${exhibitor.name} - ${exhibitor.category}`,
      new Date('2024-10-26 10:00:00'),
      new Date('2024-10-26 18:00:00'),
      {
        description: `攤位:${exhibitor.location}\n聯絡:${exhibitor.contact}`,
        location: exhibitor.location
      }
    );
  });
}

1.3 Google Sites動態網站

<!-- 嵌入式攤位地圖 -->
<div id="exhibitor-map">
  <script>
    // 從Google Sheets即時載入攤位資訊
    function loadExhibitorMap() {
      const sheetUrl = 'https://docs.google.com/spreadsheets/d/YOUR_SHEET_ID';
      
      fetch(`${sheetUrl}/gviz/tq?tqx=out:json`)
        .then(response => response.text())
        .then(data => {
          const jsonData = JSON.parse(data.substr(47).slice(0, -2));
          renderMap(jsonData);
        });
    }
    
    function renderMap(data) {
      const mapContainer = document.getElementById('map-container');
      data.table.rows.forEach(row => {
        const exhibitor = {
          name: row.c[0].v,
          location: row.c[1].v,
          category: row.c[2].v,
          features: row.c[3].v
        };
        
        const marker = createMapMarker(exhibitor);
        mapContainer.appendChild(marker);
      });
    }
  </script>
</div>

2. AI應用系統實作

2.1 客家美食AI推薦系統

import google.generativeai as genai
from google.cloud import vision
import qrcode
import json

class HakkaFoodAI:
    def __init__(self, api_key):
        genai.configure(api_key=api_key)
        self.model = genai.GenerativeModel('gemini-pro')
        self.vision_client = vision.ImageAnnotatorClient()
    
    def analyze_food(self, image_path):
        """分析食物圖片並生成介紹"""
        
        # 使用Google Vision API識別食物
        with open(image_path, 'rb') as image_file:
            content = image_file.read()
        
        image = vision.Image(content=content)
        response = self.vision_client.label_detection(image=image)
        labels = [label.description for label in response.label_annotations]
        
        # 使用Gemini生成詳細介紹
        prompt = f"""
        根據以下食物標籤,生成客家美食的詳細介紹:
        食物標籤:{', '.join(labels)}
        
        請包含:
        1. 歷史背景
        2. 營養價值
        3. 文化意義
        4. 製作工藝
        5. 推薦搭配
        
        以JSON格式回應,包含中文、英文、日文三種語言版本。
        """
        
        response = self.model.generate_content(prompt)
        return json.loads(response.text)
    
    def generate_qr_code(self, food_info, food_id):
        """生成包含食物資訊的QR Code"""
        
        # 建立食物資訊URL
        info_url = f"https://nantao-ai-market.com/food/{food_id}"
        
        # 生成QR Code
        qr = qrcode.QRCode(version=1, box_size=10, border=5)
        qr.add_data(info_url)
        qr.make(fit=True)
        
        img = qr.make_image(fill_color="black", back_color="white")
        img.save(f"qr_codes/food_{food_id}.png")
        
        return info_url

# 使用範例
food_ai = HakkaFoodAI(api_key="YOUR_GEMINI_API_KEY")

# 分析阿桂嬤的客家粄條
food_info = food_ai.analyze_food("images/hakka_noodles.jpg")
qr_url = food_ai.generate_qr_code(food_info, "hakka_noodles")

print("客家粄條AI分析結果:")
print(json.dumps(food_info, ensure_ascii=False, indent=2))

2.2 原住民音樂AI視覺化系統

import librosa
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import cv2
from openai import OpenAI

class MusicVisualizationAI:
    def __init__(self, openai_key):
        self.client = OpenAI(api_key=openai_key)
        
    def analyze_audio_emotions(self, audio_file):
        """分析音樂情感並生成視覺元素"""
        
        # 載入音訊檔案
        y, sr = librosa.load(audio_file)
        
        # 提取音樂特徵
        features = {
            'tempo': librosa.feature.tempo(y=y, sr=sr)[0],
            'spectral_centroid': np.mean(librosa.feature.spectral_centroid(y=y, sr=sr)),
            'mfcc': np.mean(librosa.feature.mfcc(y=y, sr=sr), axis=1),
            'chroma': np.mean(librosa.feature.chroma(y=y, sr=sr), axis=1),
            'zero_crossing_rate': np.mean(librosa.feature.zero_crossing_rate(y))
        }
        
        # 使用AI分析情感
        emotion_analysis = self.analyze_emotions_with_ai(features)
        
        # 生成視覺映射
        visual_mapping = self.create_visual_mapping(emotion_analysis, features)
        
        return visual_mapping
    
    def analyze_emotions_with_ai(self, features):
        """使用AI分析音樂情感"""
        
        prompt = f"""
        根據以下音樂特徵分析情感:
        - 節拍:{features['tempo']} BPM
        - 光譜質心:{features['spectral_centroid']}
        - 過零率:{features['zero_crossing_rate']}
        
        請分析這段音樂的:
        1. 主要情感(快樂、悲傷、平靜、激昂等)
        2. 能量等級(1-10)
        3. 建議的視覺色彩(主色調、輔助色)
        4. 視覺動態(緩慢、中等、快速)
        5. 圖案建議(山巒、流水、火焰、雲朵等)
        
        以JSON格式回應。
        """
        
        response = self.client.chat.completions.create(
            model="gpt-4",
            messages=[{"role": "user", "content": prompt}]
        )
        
        return json.loads(response.choices[0].message.content)
    
    def create_visual_mapping(self, emotions, features):
        """建立視覺映射規則"""
        
        mapping = {
            'colors': {
                'primary': emotions.get('primary_color', '#0066CC'),
                'secondary': emotions.get('secondary_color', '#FFD700'),
                'accent': emotions.get('accent_color', '#FF6B6B')
            },
            'patterns': {
                'shape': emotions.get('pattern_type', 'wave'),
                'movement': emotions.get('movement_style', 'flowing'),
                'intensity': emotions.get('energy_level', 5)
            },
            'dynamics': {
                'tempo_mapping': features['tempo'],
                'amplitude_mapping': 'spectral_centroid',
                'frequency_mapping': 'mfcc'
            }
        }
        
        return mapping
    
    def generate_realtime_visuals(self, audio_stream, led_controller):
        """即時生成視覺效果"""
        
        while True:
            # 即時分析音訊
            chunk = audio_stream.read(1024)
            features = self.extract_realtime_features(chunk)
            
            # 生成視覺效果
            visual_data = self.features_to_visual(features)
            
            # 發送到LED控制器
            led_controller.update_display(visual_data)

# 使用範例
music_ai = MusicVisualizationAI(openai_key="YOUR_OPENAI_KEY")

# 分析阿力的原住民古謠
visual_mapping = music_ai.analyze_audio_emotions("audio/indigenous_song.wav")
print("音樂視覺化分析:")
print(json.dumps(visual_mapping, ensure_ascii=False, indent=2))

2.3 農產品智慧行銷系統

from google.cloud import firestore
import google.generativeai as genai
from datetime import datetime
import uuid

class SmartFarmMarketingAI:
    def __init__(self, gemini_key):
        genai.configure(api_key=gemini_key)
        self.model = genai.GenerativeModel('gemini-pro')
        self.db = firestore.Client()
    
    def create_product_profile(self, farmer_info, product_info, images):
        """為農產品建立完整的數位檔案"""
        
        profile_id = str(uuid.uuid4())
        
        # 使用AI生成產品描述
        product_description = self.generate_product_story(farmer_info, product_info)
        
        # 分析營養成分
        nutrition_analysis = self.analyze_nutrition(product_info)
        
        # 生成行銷文案
        marketing_content = self.generate_marketing_content(product_description, nutrition_analysis)
        
        # 建立追蹤系統
        tracking_system = self.setup_tracking_system(profile_id, farmer_info)
        
        # 儲存到Firestore
        product_profile = {
            'id': profile_id,
            'farmer': farmer_info,
            'product': product_info,
            'description': product_description,
            'nutrition': nutrition_analysis,
            'marketing': marketing_content,
            'tracking': tracking_system,
            'images': images,
            'created_at': datetime.now(),
            'qr_code': self.generate_qr_code(profile_id)
        }
        
        self.db.collection('products').document(profile_id).set(product_profile)
        
        return product_profile
    
    def generate_product_story(self, farmer_info, product_info):
        """使用AI生成產品故事"""
        
        prompt = f"""
        為以下農產品生成吸引人的故事:
        
        農民資訊:
        - 姓名:{farmer_info['name']}
        - 經驗:{farmer_info['experience']}
        - 種植方式:{farmer_info['farming_method']}
        - 農場位置:{farmer_info['location']}
        
        產品資訊:
        - 名稱:{product_info['name']}
        - 品種:{product_info['variety']}
        - 種植週期:{product_info['growing_period']}
        - 特色:{product_info['features']}
        
        請生成:
        1. 農民故事(200字)
        2. 產品特色介紹(150字)
        3. 種植過程說明(200字)
        4. 品質保證說明(100字)
        5. 烹飪建議(100字)
        
        以溫馨、真實的語調撰寫,強調有機、安全、用心的特點。
        """
        
        response = self.model.generate_content(prompt)
        return response.text
    
    def analyze_nutrition(self, product_info):
        """分析營養成分並生成說明"""
        
        prompt = f"""
        為{product_info['name']}提供詳細的營養分析:
        
        產品資訊:
        - 名稱:{product_info['name']}
        - 品種:{product_info['variety']}
        - 有機認證:{product_info.get('organic', 'N/A')}
        
        請提供:
        1. 主要營養成分含量
        2. 維生素和礦物質
        3. 健康益處
        4. 適合人群
        5. 食用建議
        6. 保存方法
        
        以專業但易懂的方式說明。
        """
        
        response = self.model.generate_content(prompt)
        return response.text
    
    def setup_tracking_system(self, product_id, farmer_info):
        """建立產品追蹤系統"""
        
        tracking_data = {
            'planting_date': farmer_info.get('planting_date'),
            'harvest_date': farmer_info.get('harvest_date'),
            'growing_photos': [],
            'weather_data': [],
            'care_records': [],
            'quality_tests': [],
            'certifications': farmer_info.get('certifications', [])
        }
        
        return tracking_data

# 使用範例
farm_ai = SmartFarmMarketingAI(gemini_key="YOUR_GEMINI_API_KEY")

# 為阿伯的有機蔬菜建立檔案
farmer_info = {
    'name': '阿伯',
    'experience': '40年',
    'farming_method': '有機無毒',
    'location': '南桃鎮',
    'planting_date': '2024-08-01',
    'harvest_date': '2024-10-15',
    'certifications': ['有機認證', '產銷履歷']
}

product_info = {
    'name': '有機高麗菜',
    'variety': '台農一號',
    'growing_period': '75天',
    'features': ['無農藥', '甜度高', '口感脆嫩'],
    'organic': True
}

images = ['cabbage_growing.jpg', 'cabbage_harvest.jpg', 'cabbage_final.jpg']

product_profile = farm_ai.create_product_profile(farmer_info, product_info, images)
print("農產品檔案建立完成:")
print(f"產品ID:{product_profile['id']}")
print(f"QR Code:{product_profile['qr_code']}")

2.4 AI詩歌創作系統

import google.generativeai as genai
from textblob import TextBlob
import random

class AIPoetrySystem:
    def __init__(self, api_key):
        genai.configure(api_key=api_key)
        self.model = genai.GenerativeModel('gemini-pro')
        
        # 南桃主題詞庫
        self.nantao_themes = {
            'nature': ['山', '水', '田', '花', '樹', '風', '雲', '陽光', '月光', '星空'],
            'culture': ['客家', '原住民', '傳統', '美食', '歌謠', '節慶', '工藝', '故事'],
            'emotions': ['思念', '溫暖', '希望', '夢想', '愛', '友情', '回憶', '感動'],
            'technology': ['AI', '科技', '創新', '未來', '連結', '智慧', '數位', '進步'],
            'location': ['南桃', '小鎮', '故鄉', '家園', '社區', '鄰居', '街道', '市集']
        }
    
    def create_poem(self, keywords, style='modern', length='short'):
        """根據關鍵字創作詩歌"""
        
        # 分析關鍵字情感
        emotion_analysis = self.analyze_keywords_emotion(keywords)
        
        # 擴展相關詞彙
        expanded_themes = self.expand_themes(keywords)
        
        # 生成詩歌
        poem = self.generate_poem_with_ai(keywords, expanded_themes, emotion_analysis, style, length)
        
        # 後處理和美化
        formatted_poem = self.format_poem(poem)
        
        return {
            'poem': formatted_poem,
            'keywords': keywords,
            'emotion': emotion_analysis,
            'style': style,
            'length': length,
            'created_at': datetime.now().isoformat()
        }
    
    def analyze_keywords_emotion(self, keywords):
        """分析關鍵字的情感傾向"""
        
        combined_text = ' '.join(keywords)
        blob = TextBlob(combined_text)
        
        # 簡單的情感分析
        polarity = blob.sentiment.polarity
        
        if polarity > 0.1:
            emotion = '正面愉悅'
        elif polarity < -0.1:
            emotion = '憂鬱深沉'
        else:
            emotion = '平和寧靜'
            
        return emotion
    
    def expand_themes(self, keywords):
        """根據關鍵字擴展主題詞彙"""
        
        expanded = []
        
        for keyword in keywords:
            for category, words in self.nantao_themes.items():
                if keyword in words or any(word in keyword for word in words):
                    expanded.extend(random.sample(words, min(3, len(words))))
        
        # 去重並限制數量
        expanded = list(set(expanded))[:10]
        
        return expanded
    
    def generate_poem_with_ai(self, keywords, themes, emotion, style, length):
        """使用AI生成詩歌"""
        
        # 根據長度設定行數
        line_count = {
            'short': '4行',
            'medium': '8行',
            'long': '12行'
        }.get(length, '4行')
        
        prompt = f"""
        請為南桃小鎮創作一首{style}風格的詩歌:
        
        關鍵字:{', '.join(keywords)}
        主題詞彙:{', '.join(themes)}
        情感基調:{emotion}
        詩歌長度:{line_count}
        
        創作要求:
        1. 體現南桃小鎮的特色和魅力
        2. 融入科技與傳統的和諧
        3. 表達對家鄉的情感
        4. 使用富有詩意的語言
        5. 每行字數控制在5-7字
        6. 具有韻律感
        
        請直接輸出詩歌內容,不需要其他說明。
        """
        
        response = self.model.generate_content(prompt)
        return response.text.strip()
    
    def format_poem(self, poem_text):
        """格式化詩歌輸出"""
        
        lines = [line.strip() for line in poem_text.split('\n') if line.strip()]
        
        # 確保每行長度適中
        formatted_lines = []
        for line in lines:
            if len(line) > 10:  # 如果行太長,嘗試分割
                # 簡單的分割邏輯
                mid = len(line) // 2
                formatted_lines.append(line[:mid])
                formatted_lines.append(line[mid:])
            else:
                formatted_lines.append(line)
        
        return '\n'.join(formatted_lines)
    
    def create_interactive_interface(self):
        """建立互動介面"""
        
        interface_html = """
        <!DOCTYPE html>
        <html>
        <head>
            <title>南桃AI詩人</title>
            <meta charset="UTF-8">
            <style>
                body { font-family: '微軟正黑體', sans-serif; }
                .container { max-width: 600px; margin: 0 auto; padding: 20px; }
                .input-group { margin: 20px 0; }
                .poem-output { 
                    background: #f9f9f9; 
                    padding: 20px; 
                    border-radius: 10px; 
                    margin: 20px 0;
                    line-height: 1.8;
                    font-size: 18px;
                }
                button { 
                    background: #4CAF50; 
                    color: white; 
                    padding: 10px 20px; 
                    border: none; 
                    border-radius: 5px; 
                    cursor: pointer;
                }
            </style>
        </head>
        <body>
            <div class="container">
                <h1>🎭 南桃AI詩人</h1>
                <p>輸入關於南桃的關鍵字,AI將為您創作專屬詩歌</p>
                
                <div class="input-group">
                    <label>關鍵字(用逗號分隔):</label><br>
                    <input type="text" id="keywords" placeholder="例如:南桃,夕陽,思念" style="width: 100%; padding: 10px;">
                </div>
                
                <div class="input-group">
                    <label>詩歌風格:</label><br>
                    <select id="style" style="padding: 10px;">
                        <option value="modern">現代詩</option>
                        <option value="classical">古典詩</option>
                        <option value="folk">民謠風</option>
                    </select>
                </div>
                
                <div class="input-group">
                    <label>詩歌長度:</label><br>
                    <select id="length" style="padding: 10px;">
                        <option value="short">短詩(4行)</option>
                        <option value="medium">中詩(8行)</option>
                        <option value="long">長詩(12行)</option>
                    </select>
                </div>
                
                <button onclick="createPoem()">🎨 創作詩歌</button>
                
                <div id="poem-result" class="poem-output" style="display: none;">
                    <h3>您的專屬詩歌:</h3>
                    <div id="poem-content"></div>
                    <br>
                    <small>創作時間:<span id="creation-time"></span></small>
                </div>
            </div>
            
            <script>
                async function createPoem() {
                    const keywords = document.getElementById('keywords').value.split(',');
                    const style = document.getElementById('style').value;
                    const length = document.getElementById('length').value;
                    
                    if (!keywords[0].trim()) {
                        alert('請輸入關鍵字');
                        return;
                    }
                    
                    // 調用API創作詩歌
                    const response = await fetch('/api/create-poem', {
                        method: 'POST',
                        headers: {'Content-Type': 'application/json'},
                        body: JSON.stringify({keywords, style, length})
                    });
                    
                    const result = await response.json();
                    
                    // 顯示結果
                    document.getElementById('poem-content').innerHTML = 
                        result.poem.replace(/\n/g, '<br>');
                    document.getElementById('creation-time').textContent = 
                        new Date(result.created_at).toLocaleString();
                    document.getElementById('poem-result').style.display = 'block';
                }
            </script>
        </body>
        </html>
        """
        
        return interface_html

# 使用範例
poetry_ai = AIPoetrySystem(api_key="YOUR_GEMINI_API_KEY")

# 創作示例詩歌
keywords = ['南桃', '夕陽', '思念']
poem_result = poetry_ai.create_poem(keywords, style='modern', length='short')

print("AI創作的詩歌:")
print(poem_result['poem'])
print(f"\n情感分析:{poem_result['emotion']}")

3. VR歷史體驗系統

3.1 Unity VR應用架構

using UnityEngine;
using UnityEngine.XR;
using System.Collections;

public class NantaoHistoryVR : MonoBehaviour
{
    [Header("場景設定")]
    public GameObject[] historicalScenes;
    public AudioClip[] narratorAudio;
    
    [Header("互動元素")]
    public GameObject[] interactiveObjects;
    public Transform[] teleportPoints;
    
    private int currentSceneIndex = 0;
    private VRController vrController;
    private AudioSource audioSource;
    
    void Start()
    {
        vrController = FindObjectOfType<VRController>();
        audioSource = GetComponent<AudioSource>();
        
        // 初始化第一個歷史場景
        LoadHistoricalScene(0);
    }
    
    public void LoadHistoricalScene(int sceneIndex)
    {
        // 隱藏所有場景
        foreach (GameObject scene in historicalScenes)
        {
            scene.SetActive(false);
        }
        
        // 顯示指定場景
        if (sceneIndex < historicalScenes.Length)
        {
            historicalScenes[sceneIndex].SetActive(true);
            currentSceneIndex = sceneIndex;
            
            // 播放對應的旁白
            PlayNarration(sceneIndex);
            
            // 設定互動元素
            SetupInteractiveElements(sceneIndex);
        }
    }
    
    void PlayNarration(int sceneIndex)
    {
        if (sceneIndex < narratorAudio.Length)
        {
            audioSource.clip = narratorAudio[sceneIndex];
            audioSource.Play();
            
            // 顯示字幕
            ShowSubtitles(sceneIndex);
        }
    }
    
    void ShowSubtitles(int sceneIndex)
    {
        string[] subtitles = {
            "這是50年前的南桃小鎮,當時還是純樸的農村...",
            "客家先民在這裡開墾,建立了美麗的家園...",
            "原住民朋友與客家鄉親和諧共處,形成多元文化..."
        };
        
        if (sceneIndex < subtitles.Length)
        {
            UIManager.Instance.ShowSubtitle(subtitles[sceneIndex]);
        }
    }
    
    void SetupInteractiveElements(int sceneIndex)
    {
        // 根據場景設定不同的互動元素
        foreach (GameObject obj in interactiveObjects)
        {
            VRInteractable interactable = obj.GetComponent<VRInteractable>();
            if (interactable != null)
            {
                interactable.SetSceneContext(sceneIndex);
            }
        }
    }
    
    // VR控制器輸入處理
    void Update()
    {
        // 檢測控制器輸入
        if (vrController.GetButtonDown(VRButton.Trigger))
        {
            HandleTriggerPress();
        }
        
        if (vrController.GetButtonDown(VRButton.Menu))
        {
            ShowTimelineMenu();
        }
    }
    
    void HandleTriggerPress()
    {
        // 射線檢測互動物件
        RaycastHit hit;
        if (Physics.Raycast(vrController.transform.position, 
                           vrController.transform.forward, out hit))
        {
            VRInteractable interactable = hit.collider.GetComponent<VRInteractable>();
            if (interactable != null)
            {
                interactable.OnInteract();
            }
        }
    }
    
    void ShowTimelineMenu()
    {
        // 顯示時間軸選單,讓使用者選擇不同時期
        TimelineUI.Instance.Show(currentSceneIndex);
    }
}

public class VRInteractable : MonoBehaviour
{
    [Header("互動設定")]
    public string interactionText;
    public AudioClip interactionAudio;
    public GameObject[] activateObjects;
    
    private int sceneContext;
    
    public void SetSceneContext(int context)
    {
        sceneContext = context;
    }
    
    public void OnInteract()
    {
        // 播放互動音效
        if (interactionAudio != null)
        {
            AudioSource.PlayClipAtPoint(interactionAudio, transform.position);
        }
        
        // 顯示互動文字
        UIManager.Instance.ShowInteractionText(interactionText);
        
        // 啟動相關物件
        foreach (GameObject obj in activateObjects)
        {
            obj.SetActive(true);
        }
        
        // 觸發特殊事件
        TriggerSpecialEvent();
    }
    
    void TriggerSpecialEvent()
    {
        switch (gameObject.name)
        {
            case "OldHouse":
                ShowHouseHistory();
                break;
            case "RiverBridge":
                ShowBridgeEvolution();
                break;
            case "TraditionalFarm":
                ShowFarmingEvolution();
                break;
        }
    }
    
    void ShowHouseHistory()
    {
        string[] houseStory = {
            "這棟老房子建於1970年,是典型的客家三合院...",
            "屋主是當地的農民,世代在這裡生活...",
            "房子見證了南桃小鎮的變遷..."
        };
        
        StartCoroutine(PlayStorySequence(houseStory));
    }
    
    IEnumerator PlayStorySequence(string[] story)
    {
        foreach (string line in story)
        {
            UIManager.Instance.ShowInteractionText(line);
            yield return new WaitForSeconds(3f);
        }
    }
}

3.2 歷史場景數據管理

class HistoricalDataManager:
    def __init__(self):
        self.historical_periods = {
            '1970s': {
                'description': '純樸農村時期',
                'buildings': ['三合院', '穀倉', '水井', '田埂'],
                'activities': ['插秧', '收割', '曬穀', '養雞'],
                'population': 1200,
                'main_industry': '農業'
            },
            '1990s': {
                'description': '工業化初期',
                'buildings': ['三合院', '工廠', '新式住宅', '柏油路'],
                'activities': ['農業', '小型製造業', '通勤工作'],
                'population': 2500,
                'main_industry': '農業+製造業'
            },
            '2010s': {
                'description': '現代化轉型',
                'buildings': ['現代建築', '超商', '網路設施', '觀光景點'],
                'activities': ['服務業', '觀光', '電子商務'],
                'population': 3200,
                'main_industry': '服務業+觀光'
            },
            '2024': {
                'description': 'AI科技時代',
                'buildings': ['智慧建築', 'AI市集', '數位中心', '科技展館'],
                'activities': ['AI應用', '創新創業', '數位服務'],
                'population': 3800,
                'main_industry': '科技創新+觀光'
            }
        }
    
    def get_period_data(self, period):
        return self.historical_periods.get(period, {})
    
    def generate_vr_scene_config(self, period):
        """為VR場景生成配置檔案"""
        
        period_data = self.get_period_data(period)
        
        scene_config = {
            'period': period,
            'skybox': f'skybox_{period}',
            'terrain': f'terrain_{period}',
            'buildings': [
                {
                    'name': building,
                    'model': f'models/{building.replace(" ", "_")}_{period}',
                    'position': self.get_building_position(building, period),
                    'interactive': True
                }
                for building in period_data.get('buildings', [])
            ],
            'characters': [
                {
                    'type': 'farmer' if period in ['1970s', '1990s'] else 'citizen',
                    'animation': self.get_character_animation(period),
                    'dialogue': self.get_character_dialogue(period)
                }
            ],
            'ambient_sounds': [
                f'audio/ambient_{period}_1.mp3',
                f'audio/ambient_{period}_2.mp3'
            ],
            'narration': f'audio/narration_{period}.mp3'
        }
        
        return scene_config

4. 即時監控與分析系統

4.1 數據收集與監控

import asyncio
import websocket
from google.cloud import firestore, monitoring_v3
import json
from datetime import datetime

class RealTimeMonitoringSystem:
    def __init__(self):
        self.db = firestore.Client()
        self.monitoring_client = monitoring_v3.MetricServiceClient()
        self.websocket_clients = []
        
    async def start_monitoring(self):
        """啟動即時監控系統"""
        
        # 同時啟動多個監控任務
        await asyncio.gather(
            self.monitor_visitor_count(),
            self.monitor_system_performance(),
            self.monitor_social_media(),
            self.monitor_exhibitor_status(),
            self.websocket_server()
        )
    
    async def monitor_visitor_count(self):
        """監控參觀人數"""
        
        while True:
            try:
                # 從各個數據源收集人數資料
                physical_count = await self.get_physical_visitor_count()
                online_count = await self.get_online_viewer_count()
                
                visitor_data = {
                    'timestamp': datetime.now(),
                    'physical_visitors': physical_count,
                    'online_viewers': online_count,
                    'total_engagement': physical_count + online_count
                }
                
                # 儲存到資料庫
                self.db.collection('monitoring').document('visitors').set(visitor_data)
                
                # 推送到WebSocket客戶端
                await self.broadcast_data('visitor_count', visitor_data)
                
                # 檢查是否需要警告
                if physical_count > 9000:  # 超過安全容量
                    await self.send_alert('visitor_overflow', physical_count)
                
                await asyncio.sleep(30)  # 每30秒更新一次
                
            except Exception as e:
                print(f"監控訪客數量時發生錯誤:{e}")
                await asyncio.sleep(60)
    
    async def get_physical_visitor_count(self):
        """獲取實體參觀人數"""
        
        # 模擬從入口感應器獲取數據
        # 實際應用中這裡會連接到IoT設備
        
        sensors_data = await self.query_iot_sensors()
        return sum(sensor['count'] for sensor in sensors_data)
    
    async def get_online_viewer_count(self):
        """獲取線上觀看人數"""
        
        # 從YouTube API獲取直播觀看數
        youtube_viewers = await self.get_youtube_live_viewers()
        
        # 從Facebook API獲取直播觀看數
        facebook_viewers = await self.get_facebook_live_viewers()
        
        # 從網站Analytics獲取即時用戶數
        website_users = await self.get_website_realtime_users()
        
        return youtube_viewers + facebook_viewers + website_users
    
    async def monitor_system_performance(self):
        """監控系統效能"""
        
        while True:
            try:
                performance_data = {
                    'timestamp': datetime.now(),
                    'cpu_usage': await self.get_cpu_usage(),
                    'memory_usage': await self.get_memory_usage(),
                    'network_bandwidth': await self.get_network_usage(),
                    'api_response_time': await self.get_api_response_time(),
                    'database_connections': await self.get_db_connections()
                }
                
                # 儲存效能數據
                self.db.collection('monitoring').document('performance').set(performance_data)
                
                # 檢查效能警告閾值
                await self.check_performance_alerts(performance_data)
                
                # 推送到監控面板
                await self.broadcast_data('system_performance', performance_data)
                
                await asyncio.sleep(60)  # 每分鐘更新一次
                
            except Exception as e:
                print(f"監控系統效能時發生錯誤:{e}")
                await asyncio.sleep(60)
    
    async def monitor_social_media(self):
        """監控社群媒體反應"""
        
        while True:
            try:
                social_data = {
                    'timestamp': datetime.now(),
                    'hashtag_mentions': await self.count_hashtag_mentions('#南桃AI市集'),
                    'facebook_engagement': await self.get_facebook_engagement(),
                    'instagram_posts': await self.get_instagram_posts(),
                    'twitter_mentions': await self.get_twitter_mentions(),
                    'sentiment_analysis': await self.analyze_social_sentiment()
                }
                
                # 儲存社群數據
                self.db.collection('monitoring').document('social_media').set(social_data)
                
                # 推送到儀表板
                await self.broadcast_data('social_media', social_data)
                
                await asyncio.sleep(300)  # 每5分鐘更新一次
                
            except Exception as e:
                print(f"監控社群媒體時發生錯誤:{e}")
                await asyncio.sleep(300)
    
    async def websocket_server(self):
        """WebSocket伺服器用於即時推送數據"""
        
        async def handle_client(websocket, path):
            self.websocket_clients.append(websocket)
            try:
                await websocket.wait_closed()
            finally:
                self.websocket_clients.remove(websocket)
        
        start_server = websockets.serve(handle_client, "localhost", 8765)
        await start_server
    
    async def broadcast_data(self, data_type, data):
        """向所有WebSocket客戶端廣播數據"""
        
        message = {
            'type': data_type,
            'data': data,
            'timestamp': datetime.now().isoformat()
        }
        
        if self.websocket_clients:
            await asyncio.gather(
                *[client.send(json.dumps(message)) for client in self.websocket_clients],
                return_exceptions=True
            )

# 監控面板前端
monitoring_dashboard_html = """
<!DOCTYPE html>
<html>
<head>
    <title>南桃AI市集即時監控</title>
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <style>
        body { font-family: Arial, sans-serif; margin: 0; padding: 20px; }
        .dashboard { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
        .widget { background: white; border: 1px solid #ddd; border-radius: 8px; padding: 20px; }
        .metric { font-size: 24px; font-weight: bold; color: #333; }
        .label { font-size: 14px; color: #666; margin-bottom: 10px; }
        .alert { background: #ff4444; color: white; padding: 10px; border-radius: 4px; margin: 10px 0; }
        .success { background: #44ff44; color: white; padding: 10px; border-radius: 4px; margin: 10px 0; }
    </style>
</head>
<body>
    <h1>🏟️ 南桃AI市集即時監控台</h1>
    
    <div class="dashboard">
        <div class="widget">
            <div class="label">現場參觀人數</div>
            <div class="metric" id="physical-visitors">-</div>
        </div>
        
        <div class="widget">
            <div class="label">線上觀看人數</div>
            <div class="metric" id="online-viewers">-</div>
        </div>
        
        <div class="widget">
            <div class="label">系統CPU使用率</div>
            <div class="metric" id="cpu-usage">-</div>
        </div>
        
        <div class="widget">
            <div class="label">網路頻寬使用</div>
            <div class="metric" id="network-usage">-</div>
        </div>
        
        <div class="widget">
            <div class="label">社群媒體提及數</div>
            <div class="metric" id="social-mentions">-</div>
        </div>
        
        <div class="widget">
            <div class="label">情感分析</div>
            <div class="metric" id="sentiment-score">-</div>
        </div>
    </div>
    
    <div id="alerts"></div>
    
    <script>
        const ws = new WebSocket('ws://localhost:8765');
        
        ws.onmessage = function(event) {
            const message = JSON.parse(event.data);
            updateDashboard(message.type, message.data);
        };
        
        function updateDashboard(type, data) {
            switch(type) {
                case 'visitor_count':
                    document.getElementById('physical-visitors').textContent = 
                        data.physical_visitors.toLocaleString();
                    document.getElementById('online-viewers').textContent = 
                        data.online_viewers.toLocaleString();
                    break;
                    
                case 'system_performance':
                    document.getElementById('cpu-usage').textContent = 
                        data.cpu_usage + '%';
                    document.getElementById('network-usage').textContent = 
                        data.network_bandwidth + ' Mbps';
                    break;
                    
                case 'social_media':
                    document.getElementById('social-mentions').textContent = 
                        data.hashtag_mentions.toLocaleString();
                    document.getElementById('sentiment-score').textContent = 
                        data.sentiment_analysis.score;
                    break;
            }
        }
        
        function showAlert(message, type = 'alert') {
            const alertDiv = document.createElement('div');
            alertDiv.className = type;
            alertDiv.textContent = message;
            document.getElementById('alerts').appendChild(alertDiv);
            
            setTimeout(() => {
                alertDiv.remove();
            }, 5000);
        }
    </script>
</body>
</html>
"""

5. 部署與維運

5.1 系統部署架構

# docker-compose.yml
version: '3.8'
services:
  # 前端Web應用
  frontend:
    build: ./frontend
    ports:
      - "3000:3000"
    environment:
      - REACT_APP_API_URL=http://api:8000
    depends_on:
      - api
  
  # 後端API服務
  api:
    build: ./backend
    ports:
      - "8000:8000"
    environment:
      - DATABASE_URL=postgresql://user:pass@db:5432/nantao_market
      - REDIS_URL=redis://redis:6379
      - GEMINI_API_KEY=${GEMINI_API_KEY}
    depends_on:
      - db
      - redis
    volumes:
      - ./logs:/app/logs
  
  # 資料庫
  db:
    image: postgres:15
    environment:
      - POSTGRES_DB=nantao_market
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=pass
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql
  
  # Redis快取
  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
  
  # 監控系統
  monitoring:
    build: ./monitoring
    ports:
      - "8765:8765"
    environment:
      - GOOGLE_CLOUD_PROJECT=${GOOGLE_CLOUD_PROJECT}
    volumes:
      - ./monitoring/config:/app/config
  
  # Nginx反向代理
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./ssl:/etc/nginx/ssl
    depends_on:
   

上一篇
07-03:Google生態系整合應用
下一篇
08-02:AI輔助演說與即時翻譯
系列文
南桃AI重生記26
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言